﻿using log4net;
using SharpML.Api.Implementation;
using SharpML.Api.Interfaces;
using SharpML.Api.Interfaces.Plugin;

namespace SharpML.Api.Abstraction.Plugin
{
    public abstract class MLEngine : PluginComponent, IMLEngine, IMLEngineEvents, IHasSortPriority
    {
        #region - Private Member Variables -

            // Simple logging pattern
            private static readonly ILog Log = LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );

            // Have each instance be uniquely identifiable
            private static long CurrentId = -1;

        #endregion
 
        #region - Public Events -

            public delegate void EngineActivity( long id, IMLEngine engine );

            public event EngineActivity OnEngineStarted = delegate( long id, IMLEngine engine ) { };

            public event EngineActivity OnEngineStopped = delegate( long id, IMLEngine engine ) { };

            public event EngineActivity OnEngineFault = delegate( long id, IMLEngine engine ) { };

            public event EngineActivity OnEngineAcquiredDataset = delegate( long id, IMLEngine engine ) { };

            //public void EngineStarted( long id, IMLEngine engine )
            //{
            //    OnEngineStarted( id, engine );
            //}

            //public void EngineStopped( long id, IMLEngine engine )
            //{
            //    OnEngineStopped( id, engine );
            //}

            //public void EngineFault( long id, IMLEngine engine )
            //{
            //    OnEngineFault( id, engine );
            //}

        #endregion

        #region - Public Properties -

            /// <summary>
            /// The unique id for this instance
            /// </summary>
            public long Id = ++CurrentId;

            public IPatternDataAdaptor DataAdaptor { get; private set; }

            public string Shape { get; private set; }

            public ComputationEngine Engine { get; private set; }

        #endregion

        #region - Base Class Overrides -

            public override Enumerations.PluginComponentType Classification
            {
                get { return Enumerations.PluginComponentType.MLEngine; }
            }

        #endregion

        #region - Abstract IFlowControl Implemenation -

            public abstract void Run();

            public abstract void Step();

            public abstract void Pause();

            public abstract void Resume();

            public abstract void Quit();

        #endregion

        #region - Virtual IPluginEngine Implemenation -

            /// <summary>
            /// Sets the data adaptor which the engine will run
            /// </summary>
            /// <param name="dataAdaptor"></param>
            public virtual void Initialize( ComputationEngine engine, IPatternDataAdaptor dataAdaptor, string shape )
            {
                // Store
                DataAdaptor = dataAdaptor;
                Shape = shape;
                Engine = engine;

                // Let subscriber know we've acquired a data adaptor and a ready to run
                OnEngineAcquiredDataset( Id, this );
            }


        #endregion

        #region - Virtual IHasSortPriority Implemenation -

            public virtual int SortPriority { get { return 0; } }

        #endregion
    }
}
